package si.unimb.src.wifisms;

import java.util.ArrayList;

import si.unimb.src.wifisms.control.AsyncDialogSender;
import si.unimb.src.wifisms.control.Database;
import si.unimb.src.wifisms.control.TaskFinishListener;
import si.unimb.src.wifisms.entity.Account;
import si.unimb.src.wifisms.entity.SMSMessage;
import si.unimb.src.wifisms.ui.RecipientsAdapter;
import si.unimb.src.wifisms.util.IValidator;
import si.unimb.src.wifisms.util.Utility;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.MultiAutoCompleteTextView;
import android.widget.Spinner;
import android.widget.TextView;

/**
 * @author perox
 * Razred s katerim ustvarimo ali uredimo sms sporočilo.
 */
public class SendSms extends Activity implements TextWatcher, OnClickListener, IValidator, TaskFinishListener, android.content.DialogInterface.OnClickListener {
	
	/**
	 * Način shranjevanja in id objekta, ki ga urejamo.
	 */
	private int id;
	private boolean editing = false;
	
	private Spinner spinner;
	private TextView stZnakov;
	private MultiAutoCompleteTextView prejemniki;
	private EditText vsebina;
	private Button saveForLater;
	private Button sendNow;
	
	private AsyncDialogSender messageSendingTask;
	private SMSMessage sendMe;

	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sendsms);
        
        // Elementi
        saveForLater = (Button)findViewById(R.id.ShraniZaKasnejeButton);
        sendNow = (Button)findViewById(R.id.PosljiZdajButton);
        spinner = (Spinner)findViewById(R.id.IzbiraRacunaSpinner);
        stZnakov = (TextView)findViewById(R.id.SteviloZnakovText);
        vsebina = (EditText)findViewById(R.id.VsebinaSMSText);
        prejemniki = (MultiAutoCompleteTextView)findViewById(R.id.PrejemnikiMultiAutoCompleteTextView);
        
        // Inicializacija
        vsebina.addTextChangedListener(this);
        
        prejemniki.setAdapter(new RecipientsAdapter(this));
        prejemniki.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
        prejemniki.addTextChangedListener(this);
        
	    setDataOnSpinner(Database.getAccounts(this));
	    
	    saveForLater.setOnClickListener(this);
	    sendNow.setOnClickListener(this);
	    
        id = getIntent().getIntExtra("id", Utility.NO_EXTRAS);
        if (id > Utility.NO_EXTRAS) {
        	 /* urejanje sporočila */
        	this.editing = true;
        	
        	SMSMessage message = Database.getMessages(this).get(id);
        	
            this.vsebina.setText(message.getMessage());
            this.prejemniki.setText(Utility.ArrayListToString(message.getRecipients())); // izpišemo tako, da odrežemo zadnjo vejico
            TextView naslov = (TextView)findViewById(R.id.NovoSporociloText);
            naslov.setText("Urejanje sporočila " + (id + 1));
            
            /* na Spinnerju označimo račun, ki ga urejamo */
            setSpinnerSelection(message.getAccount());
            
            validate();
        }
    }
    
    /**
     * Funkcija nastavi podatke na spinner.
     * @param accounts so podatki v obliki ArrayList.
     */
    public void setDataOnSpinner(ArrayList<Account> accounts) {
    	ArrayAdapter<Account> aa = new ArrayAdapter<Account>(this, android.R.layout.simple_spinner_item, accounts);
    	aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		spinner.setAdapter(aa);
		spinner.setSelection(Database.getDefaultAccountIndex(this));
	}
    
    /**
     * Funkcija označi željen objekt kot izbran. 
     * @param account je izbran objekt.
     */
    public void setSpinnerSelection(Account account) {
    	int index = Database.getAccounts(this).indexOf(account);
    	if (index == -1) {
    		Utility.makeToastNotification(this, "Izbrano sporočila je bilo napisano iz računa " + account.getDescription() + ", ampak ta račun več ne obstaja, zato sem izbral prizvet račun.");
    		index = Database.getDefaultAccountIndex(this);
    	}
    	
		spinner.setSelection(index, true);
    }

    /**
     * Funkcija se sproži, ko se spremeni tekst v določenem EditText.
     */
	@Override
	public void afterTextChanged(Editable s) {
		/* število znakov v vsebini vpiše v labelo */
		if(vsebina.length() > 0)
			stZnakov.setText("[" + vsebina.length() + "]");
		else
			stZnakov.setText("[število znakov]");
		
		/* validacija -> buttons enabled/disabled */
		validate();
	}

	@Override
	public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {}
	
	@Override
	public void onClick(View v) {

		if(v.equals(saveForLater)) { // saveForLater Button
			
			// Shranimo sporočilo
			newMessage(this.editing);
			
		} else if(v.equals(sendNow)) { // sendNow Button
			
			// Pošljemo sporočilo (takoj)
			if(this.id < 0) {
			
				// novo sporocilo
				sendMe = form2message(new SMSMessage());
			
			} else {
			
				// uredimo staro
				sendMe = form2message(Database.getMessages(this).get(this.id));
				
			}
			
			messageSendingTask = new AsyncDialogSender(this);
			messageSendingTask.addListener(this);
			messageSendingTask.execute(sendMe);

		}
	}
	
	/**
	 * 
	 * Iz forme se zgenerira instanca SMSMessage z vsemi vnešenimi podatki.
	 * 
	 * @return SMS sporočilo
	 * 
	 */
	private SMSMessage form2message(SMSMessage newMsg) {
	
		// TODO: če je kakšna napaka v prejemnikih (format), prikaže AlertBuilder
		// ampak to mora prikazati takrat, ko proba poslati SMS, a mu webservice to zavrne...
		Account account = (Account)spinner.getSelectedItem();
		newMsg.setAccount(account);
		newMsg.setRecipients(Utility.StringToArrayList(prejemniki.getText().toString()));
		newMsg.setMessage(vsebina.getText().toString());
		
		return newMsg;
		
	}
	
	/**
	 * Funkcija shrani novo ali urejeno sporočilo v bazo.
	 * @param edit je način shranjevanja
	 */
	public void newMessage(boolean edit) {
		
		// Spremenljivka
		SMSMessage newMsg;
		
		if(edit == false) {
			
			// shranimo novo sporočilo
			newMsg = form2message(new SMSMessage());
			Database.getMessages(this).add(newMsg);
			
		} else {
			
			// uredimo sporocilo
			form2message(Database.getMessages(this).get(this.id));
			
		}
		
		Database.persist(this);
		finish();
		
	}

	@Override
	public void validate() {
		
		if(vsebina.length() > 0 && prejemniki.length() > 3 && spinner.getSelectedItem() != null) {
			saveForLater.setEnabled(true);
			sendNow.setEnabled(true);
		} else {
			saveForLater.setEnabled(false);
			sendNow.setEnabled(false);
		}
	}

	/**
	 * 
	 * Ta metoda se pokliče ko se pošiljanje sporočila zaključi.
	 * Namen: pokazati Toast in izprazniti formo.
	 * 
	 */
	@Override
	public void onTaskFinish() {
		
		// v primeru da preklicemo, ima status waiting (v tem primeru nocemo pokazati obvestila)
		if(sendMe.getStatus() != SMSMessage.STATUS_WAITING) {

			new AlertDialog.Builder(this)
			.setTitle("Konec")
			.setMessage(sendMe.getStatusString())
			.setNeutralButton("OK", this)
			.show();
			
		}
		
	}

	@Override
	public void onClick(DialogInterface arg0, int arg1) {

		// pri uspesnem posiljanju zapremo trenutno aktivnost
		if(sendMe.getStatus() == SMSMessage.STATUS_SENT) {
			
			finish();
		
		}
		
	}
	
}